package com.mueeee.webspringboot3.service.proxy;

import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
import jakarta.annotation.PreDestroy;
import net.lightbody.bmp.BrowserMobProxy;
import net.lightbody.bmp.BrowserMobProxyServer;
import net.lightbody.bmp.filters.RequestFilter;
import net.lightbody.bmp.filters.ResponseFilter;
import net.lightbody.bmp.util.HttpMessageContents;
import net.lightbody.bmp.util.HttpMessageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

/**
 * @author chenghui
 * @date 2023/12/18 23:50
 */
@Service
public class ProxyService implements CommandLineRunner {
    private static final Logger log = LoggerFactory.getLogger(ProxyService.class);
    public static BrowserMobProxy proxy;
    @Autowired private Environment env;

    public void startProxyService() {
//        final Environment env = SpringUtil.getEnvironment();
        Integer port = Integer.parseInt(env.getProperty("mob.proxy.port", "12511"));
        log.info("startProxyService:port:{}", port);
        proxy = getProxyServer(port);
        // get the JVM-assigned port and get to work!
        // int port = proxy.getPort();
//        proxy.addRequestFilter(testBing);

        // responses are equally as simple:
        proxy.addResponseFilter(testBing1);
    }

    private void filter(HttpResponse response, HttpMessageContents contents, HttpMessageInfo messageInfo) {

    }

    public static BrowserMobProxy getProxyServer(Integer port) {
        BrowserMobProxy proxy = new BrowserMobProxyServer();
        proxy.setTrustAllServers(true);
        proxy.start(port);
        log.info("getProxyServer:port:{}", port);
        return proxy;
    }

    public static void stopBrowserMobProxy() {
        if (proxy != null && proxy.isStarted()) {
            try {
                proxy.stop();
            } catch (Exception e) {
                log.error("error", e);
            }
        }
    }

    @Override
    public void run(String... args) throws Exception {
        try {
            startProxyService();
        } catch (Exception e) {
            log.error("proxy start error:{}", e.getMessage(), e);
        }
    }

    final RequestFilter testBing = (request, contents, messageInfo) -> {
        final String originalUrl = messageInfo.getOriginalUrl();
        if (originalUrl.contains("testBing") && messageInfo.isHttps() && request.method() != HttpMethod.CONNECT) {
            // retrieve the existing message contents as a String or, for binary contents, as a byte[]
            String messageContents = contents.getTextContents();
            //log.info("originalUrl:{}", originalUrl);
            // do some manipulation of the contents
            String newContents = messageContents.replaceAll(".*", """
                        <!DOCTYPE html>
                        <html lang="en">
                        <head>
                            <meta charset="UTF-8">
                            <meta name="viewport" content="width=device-width, initial-scale=1.0">
                            <title>代理成功</title>
                        </head>
                        <body>
                            <h1>代理成功</h1>
                        </body>
                        </html>""");
            //[...]

            // replace the existing content by calling setTextContents() or setBinaryContents()
//                contents.setTextContents(newContents);
        }

        // in the request filter, you can return an HttpResponse object to "short-circuit" the request
        return null;
    };

    final ResponseFilter testBing1 = (response, contents, messageInfo) -> {
        final String originalUrl = messageInfo.getOriginalUrl();
        if (originalUrl.contains("testBing") && messageInfo.isHttps() && response.status() == HttpResponseStatus.OK) {
            // log.info("originalUrl:{}", originalUrl);
            contents.setTextContents("""
                        <!DOCTYPE html>
                        <html lang="en">
                        <head>
                            <meta charset="UTF-8">
                            <meta name="viewport" content="width=device-width, initial-scale=1.0">
                            <title>代理成功</title>
                        </head>
                        <body>
                            <h1>代理成功</h1>
                        </body>
                        </html>""");
        }
        filter(response, contents, messageInfo);
    };

    @PreDestroy
    public void destroy() {
        log.info("Callback triggered - @PreDestroy.");
        proxy.stop();
    }
}
